﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using BrasilFramework.Controle.Silverlight.Comum;
using BrasilFramework.Controle.Silverlight.Conversores;

namespace BrasilFramework.Controle.Silverlight
{
    public partial class ListaTroca
    {

        public ListaTroca()
        {
            InitializeComponent();
            DataContext = this;
        }

        private readonly List<ListaItemBase<object>> listaOrigem = new List<ListaItemBase<object>>();
        private readonly List<ListaItemBase<object>> listaDestino = new List<ListaItemBase<object>>();

        public static readonly DependencyProperty TituloOrigemPropriedade = DependencyProperty.Register("TituloOrigem",
                                                                                                   typeof(string),
                                                                                                   typeof(ListaTroca),
                                                                                                   new PropertyMetadata(Comum.Mensagem.Origem));

        public static readonly DependencyProperty TituloDestinoPropriedade = DependencyProperty.Register("TituloDestino",
                                                                                                   typeof(string),
                                                                                                   typeof(ListaTroca),
                                                                                                   new PropertyMetadata(Comum.Mensagem.Destino));

        /// <summary>
        /// Título da lista de origem.
        /// </summary>
        [Category("Formatação")]
        public string TituloOrigem
        {
            get { return GetValue(TituloOrigemPropriedade).ToString(); }
            set { SetValue(TituloOrigemPropriedade, value); }
        }

        /// <summary>
        /// Título da lista de destino.
        /// </summary>
        [Category("Formatação")]
        public string TituloDestino
        {
            get { return GetValue(TituloDestinoPropriedade).ToString(); }
            set { SetValue(TituloDestinoPropriedade, value); }
        }

        public int TotalSelecionado
        {
            get { return listaDestino.Count; }
        }

        public IEnumerable<T> ListaDestino<T>()
        {
            return listaDestino.Select(item => item.Conteudo).OfType<T>();
        }

        public void Carregar(string chaveObjeto, IEnumerable<object> fonteOrigem, IEnumerable<object> fonteDestino = null)
        {
            listaOrigem.Clear();

            if (fonteOrigem != null)
                listaOrigem.AddRange(
                    fonteOrigem.Select(
                        item =>
                        new ListaItemBase<object>
                            {
                                Chave = (string)new ConversorObjetoTexto().Convert(item, item.GetType(), chaveObjeto, null),
                                Conteudo = item
                            }).ToList());

            listaDestino.Clear();

            if (fonteDestino != null)
                listaDestino.AddRange(
                    fonteDestino.Select(
                        item =>
                        new ListaItemBase<object>
                            {
                                Chave = (string)new ConversorObjetoTexto().Convert(item, item.GetType(), chaveObjeto, null),
                                Conteudo = item
                            }).ToList());

            AtualizarLista();
        }

        #region Implementação do Controle

        private void AtualizarLista()
        {
            AtualizarListaOrigem();
            AtualizarListaDestino();

            listaOrigem.ForEach(item => item.Selecionado = false);
            listaDestino.ForEach(item => item.Selecionado = false);
        }

        private IEnumerable<ListaItemBase<object>> ListaOrigemFiltrada
        {
            get
            {
                return listaOrigem.Where(
                    item => item.Chave.IndexOf(txtOrigem.Text, StringComparison.OrdinalIgnoreCase) > -1)
                    .OrderBy(item => item.Chave);
            }
        }

        private IEnumerable<ListaItemBase<object>> ListaDestinoFiltrada
        {
            get
            {
                return listaDestino.Where(
                    item => item.Chave.IndexOf(txtDestino.Text, StringComparison.OrdinalIgnoreCase) > -1)
                    .OrderBy(item => item.Chave);
            }
        }

        private void AtualizarListaOrigem()
        {
            lstOrigem.ItemsSource = ListaOrigemFiltrada;
        }


        private void AtualizarListaDestino()
        {
            lstDestino.ItemsSource = ListaDestinoFiltrada;
        }

        private void TrocarLista(List<ListaItemBase<object>> origem, IEnumerable<ListaItemBase<object>> listaOrigemFiltrada,
                                    List<ListaItemBase<object>> destino, bool apenasSelecionado)
        {
            destino.AddRange(listaOrigemFiltrada.Where(item => item.Selecionado || !apenasSelecionado));
            listaOrigemFiltrada.Where(item => item.Selecionado || !apenasSelecionado).ToList()
                                .ForEach(item => origem.Remove(item));
            AtualizarLista();
        }

        private void AdicionarItemListaDestino(bool apenasSelecionado)
        {
            TrocarLista(listaOrigem, ListaOrigemFiltrada, listaDestino, apenasSelecionado);
        }

        private void RemoverItemListaDestino(bool apenasSelecionado)
        {
            TrocarLista(listaDestino, ListaDestinoFiltrada, listaOrigem, apenasSelecionado);
        }

        private void btnAdicionar_Click(object sender, RoutedEventArgs e)
        {
            AdicionarItemListaDestino(true);
        }

        private void btnAdicionarTodos_Click(object sender, RoutedEventArgs e)
        {
            AdicionarItemListaDestino(false);
        }

        private void btnRemover_Click(object sender, RoutedEventArgs e)
        {
            RemoverItemListaDestino(true);
        }

        private void btnRemoverTodos_Click(object sender, RoutedEventArgs e)
        {
            RemoverItemListaDestino(false);
        }

        private void txtOrigem_TextChanged(object sender, TextChangedEventArgs e)
        {
            AtualizarListaOrigem();
        }

        private void txtDestino_TextChanged(object sender, TextChangedEventArgs e)
        {
            AtualizarListaDestino();
        }

        #endregion

    }
}
